package com.bzkj.web.controller.warehouse;

import com.bzkj.basicinfo.domain.warehouse.BarRelation;
import com.bzkj.basicinfo.domain.warehouse.PdaBillsList;
import com.bzkj.basicinfo.domain.warehouse.dto.BarRelationRequest;
import com.bzkj.basicinfo.service.warehouse.IBarRelationService;
import com.bzkj.basicinfo.service.warehouse.IPdaBillsListService;
import com.bzkj.common.annotation.Log;
import com.bzkj.common.core.controller.BaseController;
import com.bzkj.common.core.domain.AjaxResult;
import com.bzkj.common.core.page.TableDataInfo;
import com.bzkj.common.enums.BusinessType;
import com.bzkj.common.exception.ServiceException;
import com.bzkj.common.utils.StringUtils;
import com.bzkj.common.utils.poi.ExcelUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 单据主表Controller
 * 
 * @author lixinyu
 * @date 2025-06-13
 */
@RestController
@RequestMapping("/wareHouse/list")
public class PdaBillsListController extends BaseController
{
    @Resource
    private IPdaBillsListService pdaBillsListService;

    @Resource
    private IBarRelationService barRelationService;

    @Value("${refUserId}")
    private String refUserId;

//    /**
//     * 查询单据主表列表
//     */
//    @PreAuthorize("@ss.hasPermi('wareHouse:list:list')")
//    @GetMapping("/list")
//    public TableDataInfo list(PdaBillsList pdaBillsList)
//    {
//        startPage();
//        List<PdaBillsList> list = pdaBillsListService.selectPdaBillsListList(pdaBillsList);
//        return getDataTable(list);
//    }

    /**
     * 查询单据明细列表（以批次号和药品名称为主）
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:list')")
    @GetMapping("/detailList")
    public TableDataInfo detailList(PdaBillsList pdaBillsList)
    {
        startPage();
        List<PdaBillsList> list = pdaBillsListService.selectPdaBillsDetailList(pdaBillsList);
        return getDataTable(list);
    }

    /**
     * 批量导出选中的单据数据（包含明细和追溯码信息）
     */
    @Log(title = "单据主表", businessType = BusinessType.EXPORT)
    @PostMapping("/exportSelected")
    public void exportSelected(HttpServletResponse response, @RequestParam String billsIDs)
    {
        if (StringUtils.isEmpty(billsIDs)) {
            throw new ServiceException("请选择要导出的单据");
        }

        String[] billsIDArray = billsIDs.split(",");
        if (billsIDArray.length == 0) {
            throw new ServiceException("请选择要导出的单据");
        }

        // 设置响应超时时间为10分钟
        response.setHeader("Connection", "keep-alive");
        response.setHeader("Keep-Alive", "timeout=600, max=1000");
        pdaBillsListService.exportSelectedBillsWithDetails(response, billsIDArray);
    }

    /**
     * 获取单据主表详细信息
     */
    @GetMapping(value = "/{BillsID}")
    public AjaxResult getInfo(@PathVariable("BillsID") String BillsID)
    {
        return success(pdaBillsListService.selectPdaBillsListByBillsID(BillsID));
    }

    /**
     * 新增单据主表
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:add')")
    @Log(title = "单据主表", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody PdaBillsList pdaBillsList)
    {
        return toAjax(pdaBillsListService.insertPdaBillsList(pdaBillsList));
    }

    /**
     * 修改单据主表
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:edit')")
    @Log(title = "单据主表", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody PdaBillsList pdaBillsList)
    {
        return toAjax(pdaBillsListService.updatePdaBillsList(pdaBillsList));
    }

    /**
     * 删除单据主表
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:remove')")
    @Log(title = "单据主表", businessType = BusinessType.DELETE)
	@DeleteMapping("/{BillsIDs}")
    public AjaxResult remove(@PathVariable String[] BillsIDs)
    {
        return toAjax(pdaBillsListService.deletePdaBillsListByBillsIDs(BillsIDs));
    }

    /**
     * 更新单据上传状态
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:edit')")
    @Log(title = "更新上传状态", businessType = BusinessType.UPDATE)
    @PutMapping("/uploadState/{billsID}/{uploadState}")
    public AjaxResult updateUploadState(@PathVariable("billsID") String billsID, @PathVariable("uploadState") String uploadState)
    {
        return toAjax(pdaBillsListService.updateUploadState(billsID, uploadState));
    }

    /**
     * 软删除单据主表（将状态改为3）
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:remove')")
    @Log(title = "软删除单据", businessType = BusinessType.UPDATE)
    @PutMapping("/softDelete")
    public AjaxResult softDelete(@RequestBody String[] billsIDs)
    {
        return toAjax(pdaBillsListService.softDeletePdaBillsList(billsIDs));
    }

    /**
     * 上传单据到易联云码平台
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:edit')")
    @Log(title = "上传单据", businessType = BusinessType.UPDATE)
    @PostMapping("/upload/{billsID}")
    public AjaxResult uploadBills(@PathVariable("billsID") String billsID, @RequestBody(required = false) Map<String, String> institutionData)
    {
        boolean success = pdaBillsListService.uploadBillsToYiLianYunMa(billsID, institutionData);
        if (success)
        {
            return success("上传成功");
        }
        else
        {
            return error("上传失败");
        }
    }

    /**
     * 获取首页统计数据
     */
    @GetMapping("/dashboard/statistics")
    public AjaxResult getDashboardStatistics()
    {
        Map<String, Object> statistics = pdaBillsListService.getDashboardStatistics();
        return success(statistics);
    }

    /**
     * 获取单据二维码信息
     */
    @GetMapping("/qrcode/{billsID}")
    public AjaxResult getQrCodeInfo(@PathVariable("billsID") String billsID)
    {
        return success(pdaBillsListService.getQrCodeInfoByBillsID(billsID));
    }


    /**
     * 根据单据ID和药品ID获取层级结构的二维码信息
     */
    @GetMapping("/qrcode/hierarchy/{billsID}/{drugID}/{drugBatchNo}")
    public AjaxResult getQrCodeHierarchyByBillsIDAndDrugID(@PathVariable("billsID") String billsID,
                                                           @PathVariable("drugBatchNo") String drugBatchNo,
                                                           @PathVariable("drugID") String drugID)
    {
        return success(pdaBillsListService.getQrCodeHierarchyByBillsIDAndDrugID(billsID,drugBatchNo, drugID));
    }

    /**
     * 根据父级码获取子码
     */
    @GetMapping("/qrcode/children/{parentCode}")
    public AjaxResult getChildCodesByParentCode(@PathVariable("parentCode") String parentCode)
    {
        return success(pdaBillsListService.getChildCodesByParentCode(parentCode));
    }

    /**
     * 获取单据明细列表（用于批次号维护）
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:query')")
    @GetMapping("/detail/{billsID}")
    public TableDataInfo getBillsDetailList(@PathVariable("billsID") String billsID)
    {
        startPage();
        List<Map<String, Object>> list = pdaBillsListService.selectBillsDetailList(billsID);
        return getDataTable(list);
    }

    /**
     * 更新明细批次号
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:update')")
    @Log(title = "批次号维护", businessType = BusinessType.UPDATE)
    @PutMapping("/detail/batchNumber")
    public AjaxResult updateDetailBatchNumber(@RequestBody Map<String, Object> updateData)
    {
        String billsID = (String) updateData.get("billsID");
        List<Map<String, Object>> details = (List<Map<String, Object>>) updateData.get("details");
        
        if (StringUtils.isEmpty(billsID)) {
            return error("单据号不能为空");
        }
        
        if (details == null || details.isEmpty()) {
            return error("明细数据不能为空");
        }
        
        int result = pdaBillsListService.updateDetailBatchNumber(billsID, details);
        return toAjax(result);
    }

    /**
     * 关联关系查询（新版本，保存单据、明细、追溯码）
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:barRelation:query')")
    @PostMapping("/barRelation/queryAndSave")
    public AjaxResult queryBarRelationAndSave(@RequestBody BarRelationRequest request)
    {
        try {
            if (StringUtils.isEmpty(request.getBarCode())) {
                return error("追溯码不能为空");
            }

            // 设置默认参数
            if(StringUtils.isEmpty(request.getEntId()) || StringUtils.isEmpty(request.getRefEntId())){
                request.setEntId(refUserId);
                request.setRefEntId(refUserId);
            }

            // 调用新的接口查询并保存数据
            Map<String, Object> result = barRelationService.queryCodeRelationAndSave(request);

            if (!(Boolean) result.get("success")) {
                return error("查询失败: " + result.get("message"));
            }

            return AjaxResult.success((String) result.get("message"), result);

        } catch (Exception e) {
            return error("查询异常: " + e.getMessage());
        }
    }

    /**
     * 获取条码关系数据列表
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:query')")
    @GetMapping("/barRelation/list")
    public TableDataInfo getBarRelationList(@RequestParam(value = "barCode", required = false) String barCode,
                                           @RequestParam(value = "noPaging", required = false, defaultValue = "false") Boolean noPaging,
                                           @RequestParam(value = "hierarchical", required = false, defaultValue = "false") Boolean hierarchical,
                                           @RequestParam(value = "interactive", required = false, defaultValue = "false") Boolean interactive)
    {
        // 如果不需要分页（如详情页面），则不启用分页
        if (!Boolean.TRUE.equals(noPaging)) {
            startPage();
        }

        List<BarRelation> list;
        if (StringUtils.isNotEmpty(barCode)) {
            if (Boolean.TRUE.equals(interactive)) {
                // 交互式查询：初始只显示输入码本身
                list = barRelationService.getInitialCodeDisplay(barCode);
            } else if (Boolean.TRUE.equals(hierarchical)) {
                // 使用层级查询逻辑（用于关联关系查询页面）
                list = barRelationService.selectChildCodesByInputCode(barCode);
            } else {
                // 使用完整查询逻辑（显示所有相关数据，包括输入码本身）
                list = barRelationService.selectCompleteBarRelationsByBarCode(barCode);
            }
        } else {
            list = barRelationService.selectAllBarRelations();
        }
        return getDataTable(list);
    }

    /**
     * 根据父级码获取关联关系子码
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:query')")
    @GetMapping("/barRelation/children/{parentCode}")
    public AjaxResult getBarRelationChildCodes(@PathVariable("parentCode") String parentCode)
    {
        try {
            if (StringUtils.isEmpty(parentCode)) {
                return error("父级码不能为空");
            }

            List<BarRelation> childCodes = barRelationService.selectDirectChildCodes(parentCode);
            return AjaxResult.success("查询成功", childCodes);
        } catch (Exception e) {
            return error("查询子码失败: " + e.getMessage());
        }
    }

    /**
     * 检测追溯码级别
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:query')")
    @GetMapping("/barRelation/detectLevel/{barCode}")
    public AjaxResult detectCodeLevel(@PathVariable("barCode") String barCode)
    {
        try {
            if (StringUtils.isEmpty(barCode)) {
                return error("追溯码不能为空");
            }

            String codeLevel = barRelationService.detectCodeLevel(barCode);
            Map<String, Object> result = new HashMap<>();
            result.put("barCode", barCode);
            result.put("codeLevel", codeLevel);
            return AjaxResult.success("检测成功", result);
        } catch (Exception e) {
            return error("检测码级别失败: " + e.getMessage());
        }
    }

    /**
     * 单据导入 - 通过单据号导入
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:billsImport:importByBillsID')")
    @PostMapping("/billsImport/importByBillsID")
    public AjaxResult importByBillsID(@RequestBody Map<String, String> request)
    {
        try {
            String billsID = request.get("billsID");
            if (StringUtils.isEmpty(billsID)) {
                return error("单据号不能为空");
            }

            // 调用A方法和B方法进行数据导入
            Map<String, Object> result = pdaBillsListService.importBillsByBillsID(billsID);

            if (!(Boolean) result.get("success")) {
                return error("导入失败: " + result.get("message"));
            }

            return AjaxResult.success((String) result.get("message"), result);
        } catch (Exception e) {
            return error("导入异常: " + e.getMessage());
        }
    }

    /**
     * 批量导入选中的单据
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:billsImport:importByBillsID')")
    @PostMapping("/billsImport/importSelectedBills")
    public AjaxResult importSelectedBills(@RequestBody Map<String, Object> request)
    {
        try {
            @SuppressWarnings("unchecked")
            List<Map<String, String>> billsData = (List<Map<String, String>>) request.get("billsData");

            if (billsData == null || billsData.isEmpty()) {
                return error("请选择要导入的单据");
            }

            // 调用批量导入方法
            Map<String, Object> result = pdaBillsListService.importSelectedBills(billsData);

            if (!(Boolean) result.get("success")) {
                return error("批量导入失败: " + result.get("message"));
            }

            return AjaxResult.success((String) result.get("message"), result);
        } catch (Exception e) {
            return error("批量导入异常: " + e.getMessage());
        }
    }

    /**
     * 查询往来单位列表（用于单据导入）
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:billsImport:query')")
    @GetMapping("/billsImport/institutions")
    public AjaxResult getInstitutions()
    {
        try {
            // 查询所有往来单位列表，前端进行过滤
            List<Map<String, Object>> institutions = pdaBillsListService.getAllInstitutionsList();
            return AjaxResult.success(institutions);
        } catch (Exception e) {
            return error("查询往来单位异常: " + e.getMessage());
        }
    }

    /**
     * 更新往来单位信息
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:billsImport:query')")
    @PostMapping("/billsImport/updateCustomer")
    public AjaxResult updateCustomerInfo()
    {
        try {
            // 调用SOAP接口更新往来单位信息
            Map<String, Object> result = pdaBillsListService.updateCustomerInfo();

            if (!(Boolean) result.get("success")) {
                return error("更新失败: " + result.get("message"));
            }

            return AjaxResult.success((String) result.get("message"), result);
        } catch (Exception e) {
            return error("更新异常: " + e.getMessage());
        }
    }

    /**
     * 单据导入 - 通过时间段导入
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:billsImport:importByDateRange')")
    @PostMapping("/billsImport/importByDateRange")
    public AjaxResult importByDateRange(@RequestBody Map<String, String> request)
    {
        try {
            String startDate = request.get("startDate");
            String endDate = request.get("endDate");
            String institutionName = request.get("institutionName");
            String billsType = request.get("billsType");

            if (StringUtils.isEmpty(startDate) || StringUtils.isEmpty(endDate)) {
                return error("开始时间和结束时间不能为空");
            }

            // 如果没有传递单据类型，默认为出库
            if (StringUtils.isEmpty(billsType)) {
                billsType = "AO";
            }

            // 验证时间段规则
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date start = sdf.parse(startDate);
            Date end = sdf.parse(endDate);

            long diffInMillies = Math.abs(end.getTime() - start.getTime());
            long diffInDays = diffInMillies / (24 * 60 * 60 * 1000);

            // 根据是否选择往来单位来验证时间段
            if (StringUtils.isNotEmpty(institutionName)) {
                // 选择了往来单位，时间段可以是1个月内（30天）
                if (diffInDays > 30) {
                    return error("选择往来单位时，时间段不能超过1个月");
                }
            } else {
                // 没有选择往来单位，时间段只能是7天内
                if (diffInDays > 7) {
                    return error("未选择往来单位时，时间段不能超过7天");
                }
            }

            // 调用SOAP接口进行数据导入
            Map<String, Object> result = pdaBillsListService.importBillsByDateRange(startDate, endDate, institutionName, billsType);

            if (!(Boolean) result.get("success")) {
                return error("导入失败: " + result.get("message"));
            }

            return AjaxResult.success((String) result.get("message"), result);
        } catch (Exception e) {
            return error("导入异常: " + e.getMessage());
        }
    }

    /**
     * 调试：查看指定追溯码的所有相关数据
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:query')")
    @GetMapping("/barRelation/debug/{barCode}")
    public AjaxResult debugBarRelationData(@PathVariable("barCode") String barCode)
    {
        try {
            Map<String, Object> debugInfo = new HashMap<>();

            // 1. 查询BarRelation表中的所有相关数据
            List<BarRelation> barRelations = barRelationService.selectBarRelationsByBarCode(barCode);
            debugInfo.put("barRelations", barRelations);
            debugInfo.put("barRelationsCount", barRelations.size());

            // 2. 按级别分组
            Map<String, List<BarRelation>> groupedByLevel = new HashMap<>();
            for (BarRelation relation : barRelations) {
                String level = relation.getCodeLevel();
                groupedByLevel.computeIfAbsent(level, k -> new ArrayList<>()).add(relation);
            }
            debugInfo.put("groupedByLevel", groupedByLevel);

            // 3. 检测输入码级别
            String inputCodeLevel = barRelationService.detectCodeLevel(barCode);
            debugInfo.put("inputCodeLevel", inputCodeLevel);

            return AjaxResult.success("调试信息获取成功", debugInfo);
        } catch (Exception e) {
            return error("获取调试信息失败: " + e.getMessage());
        }
    }

    /**
     * 导出条码关系数据
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:export')")
    @Log(title = "条码关系", businessType = BusinessType.EXPORT)
    @PostMapping("/barRelation/export")
    public void exportBarRelation(HttpServletResponse response, @RequestParam(value = "barCode", required = false) String barCode)
    {
        List<BarRelation> list;
        if (StringUtils.isNotEmpty(barCode)) {
            list = barRelationService.selectBarRelationsByBarCode(barCode);
        } else {
            list = barRelationService.selectAllBarRelations();
        }
        ExcelUtil<BarRelation> util = new ExcelUtil<BarRelation>(BarRelation.class);
        util.exportExcel(response, list, "条码关系数据");
    }

    /**
     * 批量导出选中的条码关系数据
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:export')")
    @Log(title = "条码关系", businessType = BusinessType.EXPORT)
    @PostMapping("/barRelation/exportSelected")
    public void exportBarRelationSelected(HttpServletResponse response, @RequestParam String curCodes)
    {
        if (StringUtils.isEmpty(curCodes)) {
            throw new ServiceException("请选择要导出的追溯码");
        }

        String[] curCodeArray = curCodes.split(",");
        if (curCodeArray.length == 0) {
            throw new ServiceException("请选择要导出的追溯码");
        }

        List<BarRelation> list = barRelationService.selectBarRelationsByCurCodes(Arrays.asList(curCodeArray));
        ExcelUtil<BarRelation> util = new ExcelUtil<BarRelation>(BarRelation.class);
        util.exportExcel(response, list, "选中追溯码数据");
    }

    /**
     * 根据单据ID导出条码关系数据
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:export')")
    @Log(title = "条码关系", businessType = BusinessType.EXPORT)
    @PostMapping("/barRelation/exportByBillsID")
    public void exportBarRelationByBillsID(HttpServletResponse response, @RequestParam String billsID)
    {
        if (StringUtils.isEmpty(billsID)) {
            throw new ServiceException("单据ID不能为空");
        }

        List<BarRelation> list = barRelationService.selectBarRelationsByBillsID(billsID);
        ExcelUtil<BarRelation> util = new ExcelUtil<BarRelation>(BarRelation.class);
        util.exportExcel(response, list, "单据追溯码数据");
    }

    /**
     * 删除条码关系数据
     */
    @PreAuthorize("@ss.hasPermi('wareHouse:list:remove')")
    @Log(title = "条码关系", businessType = BusinessType.DELETE)
    @DeleteMapping("/barRelation/{curCodes}")
    public AjaxResult removeBarRelation(@PathVariable String[] curCodes)
    {
        List<String> curCodeList = Arrays.asList(curCodes);
        return toAjax(barRelationService.deleteBarRelationsByCurCodes(curCodeList));
    }
}
